- web6047 - (2021/09/10(金) 現在、システム調整中のため、一部の表示がおかしいかもしれません)

 homepage6047 Top Page







2018/7 /31(火)

現在、日ごろ自分が作っているプログラムをその都度その都度、このホームページで紹介するようにしています。

マニアックな内容なんですが、将来私が作成するロールプレイングゲームの下地になる試作のプログラムです。


今日は、これまで作成した以下の2つのプログラムを合体させてみました。

  1. 昨日7/30(月)のプログラム
    一連のアニメを Anm オブジェクトにまとめた。
    一連のアニメが終了したら callback 関数を呼び出すようにした。
     
  2. 7/15(日)の「batch」
    JavaScript を1行1行読み取って自前で実行する(自前の簡易的な JavaScript エンジン)。
    行に //anm100 というコメントがあったらその行は 100 ミリ秒遅れて実行し、アニメを実現する

fig.
▲アニメが終わると別のアニメを開始

この2つを合体させるとプログラマブルなアニメが実現できて、結構目玉なんです。

左の画像をクリックするとJavaScriptを実行します。

最初に2つの四角がそれぞれの動きで中央に寄ります(アニメ1)。その後、「スライムがあらわれた!」と画面に文字を1文字ずつ表示します(ア ニメ2)。

アニメ1を実行する行は //susupend というコメントがついているので、アニメ1を実行後に自前のエンジンは停止します。そしてアニメ1がアニメを終了すると、「program.resume();」という内 容のcallback関数が呼ばれます。停止していた自前のエンジンが再開され、「スライムがあらわれた!」というアニメ2が実行されます。

これが今回の合体の求める結果です。

しかし、残念ながら「batch」にいくつか下記のような不備があることが分かりました。



意外と大きなミスで恥ずかしい…。

私のプログラムを参考にする人はほとんどいないはずと思っていますが、以上の通り不備をお知らせしておきます。

「batch」については、情報処理試験に出てきそうな「構文解析」にならって作ったほうが良いかなと思います。

今回のプログラムリスト

プログラムリストが呼ぶ外部スクリプト「batch.js」


2018/7 /30(月)

fig.
▲RPG開発に必要な合理的なアニメ

RPG開発に必要な合理的なアニメ のサンプルプログラムです。

将来のプログラムの下ごしらえなプログラムなのでまだイケてないつまらない状態です。

左の画像をクリックすると JavaScript を実行します。

実行すると、赤い四角はぴょんぴょんジャンプして、右側の緑の四角はサイン波状に動きます。また、背景色が白←→黒の変化を繰り返します。

このプログラムのポイントは以下の通り。

  • 一連のアニメを合理的にAnmにまとめている。 大きな目的。
  • 一連のアニメの終了でcallbackが実行できている。 大きな目的。
    (サンプルではreverseになっていて終了しないのでcallbackは呼ばれません)
    (callbackとは、”プログラム中で、呼び出し先の関数の実行中に実行されるように、あらかじめ指定しておく関数” です)
  • 関数での移動ができている。

プログラムリストを表示

今後の開発のどの部分で使うかと言うと…

  • SVC(Side View Character)の制御
  • RPGの各種イベントの実行
  • また、普通のホームページの飾りのアニメとしても使用できます。(汎用的)


SVCとは

SVC(Side View Character) とは大体、以下のようなものです。

ガンダムのプラモデルみたいに体のパーツの関節を動かせば、いろいろなポーズをとらせることができる、というものです。

SVC(Side View Character) という言葉は私が勝手に作った名称で、ちょっと検索した限りでは世間や業界には無いみたいです。決して難しい技術ではないので、誰でもこの手法を使ってアニメが作れるし、 そういう独自性の低いシンプルな技術には知的財産権のようなものもないと思って良いでしょう。SVCという名称もそのままなので、誰かが占有するというも のでもない気がします。なので、いいなと思ったらあなたもやってみると良いと思います。


fig.
▲SVCの表現力がわかるサンプル

SVCの基本的な動作の試作プログラム

左の画像リンクをクリックすると JavaScript プログラムのページを開きます。

ページを開いたら、下部のいくつかのリンクをクリックすると、ヌンチャクみたいなものがいろいろなポーズを取ったり、あちこち動いたりします。



fig.
▲かわいい感じの女の子を
ガンプラみたいに動かせる

SVCのポーズのエディター

左の画像リンクをクリックすると JavaScript プログラムのページを開きます。

ちょっとかわいい感じの女の子がカッコよく決めているんで一番見栄え(みばえ)がするかもしれないです。

画面左の身体のパーツリストのスライダを動かすと関節が動きます。

いろいろボタンがあって、いくつかの機能を盛り込んでありますが、説明はしていません。

でも、ボタンの名前から機能の動きを ある程度推測できるようにしたつもりです。



fig.
▲リアルなジャンプに注目

SVCのポーズのエディター

左の画像リンクをクリックすると JavaScript プログラムのページを開きます。

上のエディターと同じものですが、ジャンプなどアニメする機能があります。

ただし、作ったポーズを保存してアニメを新しく作る機能はありません。


<単純なプログラムで、複雑なアニメになる事実>

あるポーズのデータを決めておいて、別のポーズも決めておきます。前のポーズから後のポーズへ各関節が一斉に同じ時間内で動くと、複雑なアニメ になります―――

スケルトンのプログラムで直立からジャンプすると、だいぶ複雑なアニメーションでびっくりするかもしれませんが、「直立」、「ジャンプ頂点 時」、「着地時」の3つのポーズを作成し、あとは各ポーズの各関節の角度を前ポーズの値から後ポーズの値へと各関節同じ時間内に少しずつ変化させ ているだけなんです。それだけで複雑なアニメになっています。

たとえば、前ポーズで右ひじの角度が30度で、後ポーズが60度、これを3秒でアニメするとしたら、1秒当たり10度動けば前ポーズから後ポー ズへのアニメは完了します。実際は1秒ごとではなく、100msくらいの間隔でアニメしているので、100ms当たり1度動いていることになりま す。そのとき、いっぽうで、例えば右ひざの角度が0度から90度まで同じ3秒で変化するとしたら、100ms当たり3度動きます。そうやって各関 節それぞれ動く量が異なっていますが、アニメが完了する時間は同じになっています。ポーズからポーズへと各関節が一斉に動きます。

各関節は親子関係になっています。「親が30度傾いていたら、子はその30度傾いている状態を0度とします」(これを「相対的な位置関係」と 言ったり、「ローカル座標系」と言ったりします)。たとえば、ひじをのばした状態を0度だとします。そしてひじの親は肩です。肩を90度曲げる と、ひじも一緒に動きますがひじの0度を動かしたわけではないのでひじの角度は0度を保っています。「親である肩が90度傾いたら、子であるひじ はその90度傾いている状態を0度とします」。ひじを90度曲げた状態で肩を90度曲げると、ひじも一緒に動きますがひじの90度は保っていま す。このローカル座標のしくみも、複雑なアニメのモトになっています。(ローカル座標は必ず必要というわけではありません。絶対座標よりも座標計 算が楽になり便利だ、というものです)

この「ローカル座標系」は難しそうに聞こえたかもしれませんが、もっと図を使って順序立てて説明すればわかってもらえる内容だと思います。ロー カル座標系を JavaScript の canvas で実現するには、save(), restore(), translate(), rotate() などのcanvasの関数を使います。そんなに複雑なプログラムにはなりません。ただし、考え方は、これらを使わない通常の画面描画(画面の左上を0,0として座標を指定 する絶対的な描画)と比べるとやや特殊(ローカル座標系の考え方は特殊)なので慣れるまでは勝手が難しいかもしれないです。勝手がわかると、いつ でもどこでもローカル座標系に頼ってしまうほど便利です。



2018/7 /27(金)

fig.
▲大きな画像へリンク
PDFはこちら

「ゲームの自分史」という表を作ってみました。

子供のころからどんなゲームで遊んできたかを知ることで、私がどういう人物かつかみどころが出てくるんじゃないかとちょっと思ったんですが…。




最近、ニュースで、「残業150時間働かされて、それを苦に自殺」という話を時々聞きます。

さきほどもニュースで「残業160時間で自殺」というのがありました。

10年位前の話ですが、私の知り合いは残業300時間働いて、「300時間だぞ!」と笑っていました。

私とその人は同僚で、会社の寮で同じ部屋に住んでいたので、よく知っているんですが、残業300時間を記録した後、「やっと休みだ!」と喜んでいた矢 先、アルバイトから電話が入り、「今日風邪ひいたんでー」みたいな内容だったらしく、寝床の上でしくしくと泣いていました。アルバイトが休みなら代わりに 誰かがお店に出なければならず、それはその人(店長)の役目なんです。

かわいそうだったので「私が代わりに出勤しましょうか?」と言ってあげたかったですが、私も受け持ちの店に暇がないので助けられませんでした。

残業300時間という世界は、1日10時間の残業を行い、それを休みなく1か月行うと300時間です。

自慢じゃないですが、私はたしか残業250時間が最高でした。毎月残業200時間前後を基準にしていました。

同じような環境の同僚が10人くらいいて、そのなかで不満を言う人は一人もいませんでした。みんな同じだったし、仕事内容を理解していたので、不満を言 うことのほうがおかしかったと思います。

たぶん残業150時間で自殺してしまった人は、もし残業300時間で笑ったり泣いたりしている人を見たら、自殺を思いとどまったかもしれません。

ただ、私のその時の会社は上司たちが明るくまじめだったので、みんな理解して仕事ができていたのかもしれません。もし上司が冷たい人たちでそこから逃げ られないとすれば自殺なんてことも考えることもあり得るかもしれません。


余談ですが、残業200時間を基準に5年ほど働いた私は、現在、一番下の記事でも書きましたが、体が壊れてしまいました。その仕事を辞めた直後、急速に 体が不調になって、のぼせたような感じでフラフラとしてしまって います。アメリカの大統領だったレーガンさんも冷戦の大きな緊張感の中で仕事をして 辞めた後は、アルツハイマー(認知症)にかかってしまったそうです。きっと緊張がゆるんで疲れがどっと押し寄せたのではないかと思います。

下の記事で書いたように、それでも私はあのときの仕事を後悔することはありません。あのときは、そのときそのときで自分で必要な仕事を選択して実行して いたので後悔がないんだと思います。お客さんのためだったり、夜の私から 仕事を引き継ぐ昼のアルバイトのためだったり。

現在フラフラになってしまって、何か人生を悲観しているか、と言ったら何も悲観していません。夢を3つ4つ持っているし、その夢に期待をしているから… かな? 時間的にも体力的にもその夢は叶わないかもしれませんが、時間がない、体力がないは、夢をあきらめる理由にならないような? なんか間違ってるか な?

残業300時間の話は異常な世界で面白いと思いますが、面白半分で実践してしまうと私のようになってしまうので誰も行わないでください。


2018/7 /21(土)

fig.
▲大きな画像へリンク

ひなたぼっこでもしに行こう、と思って近所の砂浜へ行ったら、もう海水浴をやっていました。

ただ波がちょっと粗いように見えました。



fig.
▲大きな画像へリンク

自宅から歩いて1分くらいのところにある、通勤路。

毎朝通勤で通るたびにドブ(側溝、そっこう)にゴミがたまっていて、見苦しく、何とかならないかなぁと思っていました。

そういう動機があるので、本日、個人的にクリーンアップを開始することにしました。

大事なのは、その行動が常識の範囲を超えているかどうか、自分でチェックすることです。

私のそのゴミ回収の行動が、はたから見て「異常行動」と取られるかどうかがわりと重要で、その対策として、首の周りに汗対策のハンドタオルを巻 くとか、白いシャツにジーパンといった作業しやすい格好をするとか、トング(一体成型の金属製のつまみ)を持つとか、それっぽい格好をすると良い と思います。または一人ではなく複数人で誘い合って行えばまったく問題ないと思います。人はそういう「ぱっと見」で判断するところがあるからで す。



fig.
▲大きな画像へリンク

拾ったごみはこんな感じでした。

誰かが先にちょっと清掃していたのかわかりませんが、ちょっと思ったよりも少なかったです。

それでいいんですけど、張り切っていた分、残念な気も。


週明け、通勤するとき、ゴミがなければ ヨシ!って感じです。

皆さんもやってみてはどうでしょうか? 運動不足解消にもなりますよ。

仕事で疲れていてそんな余力ないよ、というのは勘違いですよ。私も疲れているからです。

どこかゆっくりできるところ(私の場合は砂浜)へ出かけゆっくりドリンクでも飲みながら ひなたぼっこをしてからなら疲れは取れてると思うので、やってみると良いと思うんですが…

この行動は、「土曜日に一人で通勤路の清掃をした」とか「みんなで通学路のゴミ拾いをした」などと言えば人に通じると思います。人に通じる言 葉って大事だと思うので。




2018/7 /15(日)

最近やっているプログラムは以下の通りです。将来のプログラムの下ごしらえなプログラムなのでまだイケてないつまらない状態です。

下記の説明は、急いで書いたので、ちょっと分かりづらいかもしれません。


fig.
▲JavaScriptを実行するJavaScript

1. 開発時通称「batch」

思った通りに動いた!

ちゃんとアニメになっている!

プログラミングをしていて面白いのは、プログラムが自分の思った通りの動きをしてくれることと、それから、新しい動きを目の当たり(まのあた り)にしたときです。

JavaScriptをJavaScriptのエンジンに任せずに、自前のエンジン(?)で実行します。

つまり、JavaScriptを1行1行読んで、if文による分岐や、forやwhileなどの繰り返し、functionやvarなどの宣言 文など、全部自分で動きを作って動作させています。たとえばfor文は、for( i =0; i < 10; i++ ) { ... } のように書きますが、この初期化 i = 0; を実際に i = 0; とJavaScriptで実行し、 条件部分は、if( i < 10 ) { forブロックの実行を続行 } としていて、加算部分も実際に i++ を自分で実行してfor文の制御を行っています。

どうしてそんなことをするのかと言うと、”行末のコメントに //anm100 と書けばその行を100ミリ秒遅らせて実行する…” ということを実現したいからです。それができると、普通のJavaScriptの1行1行をアニメの命令としてプログラムすることができるようになります。(前にも同じ話 をしたことがあります)

左の画像リンクをクリックするとJavaScriptを実行します。

実行すると、プログラムリストの最後のほうにある、test(), test2() という関数のスクリプトを読み込んで1行1行実行します。JavaScriptコンソールに500ミリ秒のタイミングで「スライムがあらわれた!」と1文字ずつ表示しま す。test(), test2() はそれぞれ普通のJavaScriptの関数ですが、//anm500 のように書かれた部分だけは時間を遅らせて実行するのでアニメーション(今回は文字の出力ですが)になります。ふつうの関数としてJavaScriptのエンジンに実行さ せると、1文字ずつ出力しますが時間を待たずに一気に表示してしまいます。

この //anm500 と書き加えるだけでアニメーションになる、というのはまったく新しい動きで、面白いと思います。

もっとも、JavaScriptのエンジンのほう(JavaScriptのモトであるECMA Scriptを勧告している方々)で、delay() 関数(指定時間何もしないで待つ関数)を用意してくれさえすれば、私がやっている以上のことは必要ないのですが…

プログラムリストを表示



fig.
▲再帰処理を使わずに再帰する

2. 開発時通称「batch - 再帰を平で行う」

上記の「JavaScriptを実行するJavaScript」のために、「再帰処理」を「再帰処理」を使わずにプログラムします。

普通、再帰処理を行うときは、関数の中でその関数自身を呼び出すようなことをしますよね。

たとえば、function test() { ...; test(); ...; } こんな感じで。

「JavaScriptを実行するJavaScript」ではブロック構造を解釈して、入れ子のブロック構造になっているプログラムを1行1行 実行しますが、入れ子に入る際に再帰処理が必要になります(なぜなら入れ子であっても「1行ずつ実行する」といった処理は同じで、そういう場合は 再帰処理となります。たとえば、マトリョーシカを1つ1つ取り出してきれいに磨くという場合、「マトリョーシカを磨く、中のマトリョーシカを取り 出す、この手順を最初から行う」という手順(再帰処理)を実行するとすべてのマトリョーシカを綺麗にできます)。

▲マトリョーシカ(クリックするとPDFを開きます)

ふつう、JavaScriptのエンジンが行っている、関数から関数を呼び…という再帰処理では、その処理の途中で止めて、別のことを行ってか ら再び再帰処理の途中へ戻るというようなことはできません。

しかし、「JavaScriptを実行するJavaScript」の目的の ”行末のコメントに //anm100 と書けばその行を100ミリ秒遅らせて実行する…” を実現するためには、ブロックの中のブロックへという再帰処理を途中で止めて、setTimeout() というJavaScriptの関数を使って 100ミリ秒待ってから再帰処理の途中へ戻る、というようなことが必要なんです(私の考えているやり方では必要)。そこで再帰処理と同じことを再帰処理を使わずに行う方法 (関数の中でその関数を呼ばない)が必要なんです。

そのサンプルがこれです。(でも、あまり気に入った形ではありません)

左上の画像リンクをクリックするとJavaScriptを実行します。

プログラムリストを表示

プログラムリストでは 関数 explorer1() が普通の再帰処理を使った関数で、関数 explorer2() が再帰処理を使わないで同じことをする関数です。階層構造を持ったデータを親子すべて網羅する処理となっています。

explorer2() は再帰処理を途中で止めて少し待ってから続きの処理を行っています。



fig.
▲アニメのサンプル

3. 開発時通称「アニメのサンプル」

下記の3種類の変化を 同時に行いながらアニメするサンプルです。

  • 回転しながら右に移動
  • 2次関数で縦方向へ移動(放物線運動となる)
  • 色を変更

ただし、アニメが終わった後、別のアニメを続いて実行したいという場合、それはどうすればいいのか…。

その解決のために上記の「batch」を作っています。

左の画像リンクをクリックするとJavaScriptを実行します。

プログラムリストを表示



fig.
▲SVCの基本

4. 開発時通称「basic SVC」

「Side View Character」、略してSVCのもっともシンプルな基本のプログラムがこれです。

左の画像リンクをクリックするとJavaScriptを実行します。

プログラムリストを表示



fig.
▲SVCの基本にmoveBy()

5. 開発時通称「basic SVC + moveBy」

上記のサンプルに、”特定のパーツを特定の場所へ移動し、そのパーツを基準に他のパーツを描く” という機能を加えたものです。

たとえば、SVCで人間を作ったとき、足が地面に着地した状態にしたいときにこの機能(moveBy() )を使います。

左図では緑のパーツが画面の中央に移動し、他のパーツはそれに合わせて位置を移動して全体の形を維持して描かれています。

上記の「basic SVC」のほうでは便利なtranslate()関数を使って「ローカル座標」を実現できるのでシンプルに描画ができます(親子関係のある図を描く際に各パーツが親からの 相対の「ローカル座標」を使用できると、簡潔に描けて便利です。canvasのtranslate()やrotate(), save(), restore() はそれを実現してくれる関数です)が、「basic + moveBy」のほうでは、各パーツの「絶対座標」(CANVASの左上を0,0としたときの座標)がないと同機能(”特定のパーツを特定の場所へ移動し…”)を実現でき ません。

(このように誰かが行っているその人の個人的な研究というのは意味が分からないものだと思いますが、説明しようと思います)

SVC全体を何も考えないで描画したものが上記の「basic SVC」の状態だとして、また、”特定のパーツを特定の場所へ移動” した状態が左図だとします。

緑のパーツに注目すると右下へ少し移動しています。この少しの移動というのは、他のパーツも同じ量だけ移動しているのが図を見比べてわかるで しょうか。

この少しの移動というのがどれくらいなのかが分かれば、”特定のパーツを特定の場所へ移動し、そのパーツを基準に他のパーツを描く”ということ が実現できます。他のパーツも同じだけ移動して描けば良いのですから。

この少しの移動(プログラム中でdiffX, diffYという変数)の算出は、「特定のパーツをどこに移動したいのかという位置(絶対座標)」ー「元の位置=SVC全体を何も考えないで描画した「basic SVC」の状態(の絶対座標)」で算出できます(下記リンクのプログラムリストの138行目で行っています)。この「「basic SVC」の状態(の絶対座標)」を得るために、各パーツの「絶対座標」の計算が必要になります。しかし「basic SVC」のようにtranslate()を使って「ローカル座標」を実現して便利に描いている状態では絶対座標を知る手段が(探しましたが)ありません。これは「親がこの 位置、その回転を考慮、さらにその親がこの位置、その回転を考慮…」と親をさかのぼって相対座標を加算していくというような処理が必要です (115行目のgetAbsolute()メソッド)。この計算は私はくじけそうになりました。

私の毎回のこの手の説明を普通に読んでくれる人って、いないか、いても一人か二人くらいだろうなと思っています。なんせ日本語が苦手な人の文章 ですから。

左の画像リンクをクリックするとJavaScriptを実行します。


プログラムリストを表示



以上のように、いろいろプログラムしているわけですが、えんえんと続く下ごしらえをしている感じであって、「あの坂をのぼれば海が見える」という向田邦 子の文章みたいな状態になっています。


2018/7 /10(火)

独り言なんですが、イラストACというサイトで私が描いたイラストを投稿したところ(2年前くらい)、今日になってメールが届いて

「(お客さんからのダウンロードなどで)ポイントがたまり、換金可能になりました」

とのことで、数千円もらえることになりました。もらえるというか、イラストの報酬なので対価ということですが…。

そ のイラストのページ

RPGのモンスターイラストやパソコンのイラストを投稿しているんですが、モンスターにはまったく人気がなく、実用的なパソコンイラストのほうで多くの ダウンロードがあったようです。

「企業のホームページや個人のホームページなど、どのようなページにもマッチするように描いた」、というのがウケたのかな…。

ウケたと言っても他の同じ投稿している方々に比べたら大したことないのかもしれませんが…。

でも初めて自分の絵で かせいで、ちょっとだけイラストレーター気分。

2018/7 /8(日)

電気業界の月刊誌「トランジスタ技術」の年間予約購読(10,200円、年間12冊)を申し込みました。8月分から届くそうです。

今から8年前、2010年に失業して、ハローワークの「電子回路エンジニア科(4か月)」を受講して以来、2016年まで6年(?)ほど同誌を毎月1冊 ずつ購入していました。

『電気業界になるべく追いつくべく、トランジスタ技術の本の内容の数%しかわからなくても努力しよう』

という気持ちで買っていたんですが、2016年に転職して正社員から契約社員になり、収入が以前よりも減り、仕事の内容も「電子回路」から「電子機器組 み立て」に変わったこともあり、同誌の購入はやめることにしていたんです。

それで今月まで2年くらい買っていませんでした。

最近はどうも以前よりも勉強ができなくなって、どうしても遊んでしまう…。

(APB3というスペアナを購入したりして電気関係の取り組みや勉強に火が付くかな?と思いましたが付きませんでした)

遊びと言っても、誰かに何かを教えるようなホームページを作っていたりと、どこか生産的な遊び(趣味)ではあるんですが…。

このままではいけないと思って、起爆剤として「トランジスタ技術」の年間購読を導入してみたんです。

まぁ、毎月届いては積み上げて終わりとか、ありえるんですが。


ところで、自己紹介のページに載せた写真(2018年春 撮影)は健康そうに見えますが、実は私の身体は壊れています。

健康診断でそのように言われたわけではなく、自分でそう思っているだけですが…。

たとえば身体が毎日フラフラしていて、よろけて倒れそうになることがあります。その点について病院で診てもらったことがありますが「精密検査をしても結 果に出ないので何とも診断できません」と言われました。つまり、本人の主張があるだけという結果です。

他には、視力は40歳くらいまでは両目1.5を ほこっていたんですが(30年以上もプログラミングをしていて1.5!)、この1年の間に0.1とかそんな感じの視力に急にガクンと下がりました。もっと下がるんじゃない かな。

体力もだいぶ落ちて、「疲れた、疲れた」といつも言っています。

疲れに押されているせいか、以前行っていた対人関係のケアもできず、、ケアどころか、対人関係をマイナスにするようなNGな行動をとってしまったり、そ れをフォローすることもできず…。でも目の前にいる人(たとえば仕事の同僚)には、ちゃんと親切にできているし、最近そう言われて喜ばれた気もしま す、、。親切というのは、相手の仕事をやりやすく整頓してあげたり、重いものを持ってあげたり、残業や休日出勤、他の部署の手伝いも自分から進んでやって るという感じです。

身体が壊れた原因はそこ(仕事のし過ぎ)にあるのはわかっていますが、それをやらない自分は自分ではない気もする。以前の仕事のし過ぎには特に後悔の念 はなく、あのときはあの仕事を選んでそれしかなかった(半端で終わらず、きっちり終わらせる仕事のやり方を選んだ)、お客さんのためにやっていたし、当た り前の仕事をして引き継ぎの人に迷惑を掛けないというやり方も特に問題なかったと思う。(我が一生に一片の悔いなし…!! いやあるよ)